home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / YANNS3D.ZIP / PMODE32 / 3D.ASM next >
Encoding:
Assembly Source File  |  1994-09-10  |  57.7 KB  |  1,937 lines

  1. ; ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  2. ;  This is a 3D animation demo, written by Yann/Iguana
  3. ;  Credits to:
  4. ;    * Jare/Iguana for his nonjump Bresenham,
  5. ;    * Tran/Renaissance for letting us see the sources of the Amnesia demo
  6. ;    * Tran/Renaissance for his great PMODE 2.4
  7. ;
  8. ; ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  9.  
  10. ; History: 0th version: '93
  11. ;          p0th version: june 30'94 (pmode version)
  12.  
  13. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  14. ; Macros to profile the 3D engine
  15. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  16. SetBorder2      MACRO Color
  17.                 push    ax
  18.                 push    dx
  19.                 cli                     ; So that the flip-flop isn't
  20.                                         ; uninit-ed by some IRQ...
  21.                 mov     dx,3DAh
  22.                 in      al,dx           ; Init the flip-flop for the
  23.                                         ; attribute controller
  24.                 mov     dx,3C0h         ; Attribute controller port
  25.                 mov     al,31h          ; Overscan reg, don't switch ray off
  26.                 out     dx,al           ; Write Register #
  27.                 mov     al,Color
  28.                 out     dx,al           ; Write Border Color
  29.                 sti
  30.                 pop     dx
  31.                 pop     ax
  32.                 ENDM
  33.  
  34. SetBorder       MACRO Color             ; To profile
  35.                 ;SetBorder2 Color
  36.                 ENDM
  37.  
  38.         .386p
  39. code32  segment para public use32
  40.         assume cs:code32, ds:code32
  41.  
  42. include pmode.inc
  43.  
  44. public  _main
  45.  
  46. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  47. ; DATA
  48. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  49.  
  50.  
  51. ClippedFacetsBuffer DW 4096 DUP (?)
  52. ; For each facet: DW facet type
  53. ;                 DW data1 (1st byte color for solid facets)
  54. ;                 DW data2
  55. ;                 DW # of points in the facet
  56. ;                 DW n DUP (x,y,z)
  57. SortedFacetsList DW 4096 DUP (?)
  58. ; For each facet: DD offset of the next linkedlist item
  59. ;                 DD distance of the middle point ^ 2
  60. ;                 DD offset of the facet (in the Clip. buffer)
  61. SortedFacetsHeadPtr DD ?
  62. NextFreeSlotPtr DD ?
  63.  
  64. LinesBuffer1 DW 3072 DUP (?)
  65. LinesBuffer2 DW 3072 DUP (?)
  66. LinesBufferPtr DD ?
  67. NumBufferedLines1 DW ?
  68. NumBufferedLines2 DW ?
  69. NumBufferedLinesPtr DD ?
  70.  
  71. EVEN
  72. QuitPrg DW 0
  73. VGASeg  DW 0A400h
  74. ; Drawing mode:
  75. WIREFRAME   = 0
  76. SOLID       = 1
  77. Mode    DW SOLID
  78.  
  79. ; ------------------------ Description of the environment ---------------------
  80. INCLUDE ..\road.inc
  81. ; ^^^^^^^^^^^^^^^^^^^^^^^^ Description of the environment ^^^^^^^^^^^^^^^^^^^^^
  82.  
  83. ; ------------------------ Description of the movement ------------------------
  84. Movement LABEL WORD
  85.  
  86. INCLUDE ..\roadm.inc
  87.  
  88.  DW -1
  89.  
  90. ; ^^^^^^^^^^^^^^^^^^^^^^^^ Description of the movement ^^^^^^^^^^^^^^^^^^^^^^^^
  91.  
  92. CameraPts LABEL WORD
  93.         DW NUM_POINTS DUP (?,?,?)
  94.  
  95. NumFacets DW ?
  96.  
  97. ;SinTable created by Jon Beltran de Heredia
  98. ;Sines are in 8.8 fixedpoint, from 0 degrees to 360+90 degrees (in order to
  99. ; calculate the cosines with the same table)
  100. SinTbl  LABEL   WORD
  101. DW 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
  102. DW 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
  103. DW 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
  104. DW 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
  105. DW 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
  106. DW 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256
  107. DW 256,256,256,256,255,255,255,254,254,253,252,251,250,249,248
  108. DW 247,246,245,243,242,241,239,237,236,234,232,230,228,226,224
  109. DW 222,219,217,215,212,210,207,204,202,199,196,193,190,187,184
  110. DW 181,178,175,171,168,165,161,158,154,150,147,143,139,136,132
  111. DW 128,124,120,116,112,108,104,100,96,92,88,83,79,75,71
  112. DW 66,62,58,53,49,44,40,36,31,27,22,18,13,9,4
  113. DW 0,-4,-9,-13,-18,-22,-27,-31,-36,-40,-44,-49,-53,-58,-62
  114. DW -66,-71,-75,-79,-83,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
  115. DW -128,-132,-136,-139,-143,-147,-150,-154,-158,-161,-165,-168,-171,-175,-178
  116. DW -181,-184,-187,-190,-193,-196,-199,-202,-204,-207,-210,-212,-215,-217,-219
  117. DW -222,-224,-226,-228,-230,-232,-234,-236,-237,-239,-241,-242,-243,-245,-246
  118. DW -247,-248,-249,-250,-251,-252,-253,-254,-254,-255,-255,-255,-256,-256,-256
  119. DW -256,-256,-256,-256,-255,-255,-255,-254,-254,-253,-252,-251,-250,-249,-248
  120. DW -247,-246,-245,-243,-242,-241,-239,-237,-236,-234,-232,-230,-228,-226,-224
  121. DW -222,-219,-217,-215,-212,-210,-207,-204,-202,-199,-196,-193,-190,-187,-184
  122. DW -181,-178,-175,-171,-168,-165,-161,-158,-154,-150,-147,-143,-139,-136,-132
  123. DW -128,-124,-120,-116,-112,-108,-104,-100,-96,-92,-88,-83,-79,-75,-71
  124. DW -66,-62,-58,-53,-49,-44,-40,-36,-31,-27,-22,-18,-13,-9,-4
  125. DW 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
  126. DW 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
  127. DW 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
  128. DW 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
  129. DW 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
  130. DW 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256,256
  131.  
  132.  
  133. ByeMsg  DB 'Greetings to everyone in FidoNet.R34 PROASM_E & R34.DEMOS chats'
  134.         DB 0Dh,0Ah
  135.         DB 'Good bye!', 0Dh, 0Ah
  136.         DB 'Coded by Yann/Iguana', 0Dh, 0Ah
  137.         DB '$'
  138.  
  139. EVEN
  140. ;*****
  141. ; Distance: near z clipping plane
  142. ZN DW ?
  143. ;*****
  144. ; Angle: field of view (in degrees)
  145. FOV DW ?
  146. ;*****
  147. ; Distance: from the eye to the projection plane (calc as 100/sin(FOV/2))
  148. Dist DW ?
  149. ;*****
  150. ; Vector: eye coors
  151. _ex DW ?
  152. _ey DW ?
  153. _ez DW ?
  154. ; Vector: look-at point coors
  155. _ax DW ?
  156. _ay DW ?
  157. _az DW ?
  158. ; Vector: looking direction
  159. _tx DW ?
  160. _ty DW ?
  161. _tz DW ?
  162. ; Vector length: |t|
  163. _t DW ?
  164. ; Distance: lambda = sqrt(tx^2+ty^2)
  165. lambda DW ?
  166. ; 3x3 Matrix: rotation matrix to put t along z axis
  167. M11 DW ?
  168. M12 DW ?
  169. M13 DW ?
  170. M21 DW ?
  171. M22 DW ?
  172. M23 DW ?
  173. M31 DW ?
  174. M32 DW ?
  175. M33 DW ?
  176.  
  177. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  178. ; CODE
  179. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  180.  
  181. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  182. ;  Function to calc M matrix from _e and _a vectors
  183. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  184.         EVEN
  185. CalcM   PROC
  186.         ; Assure there is no overflow
  187.         mov     ax,[_ax]
  188.         cmp     ax,[_ex]
  189.         jne     CML0
  190.         mov     ax,[_ay]
  191.         cmp     ax,[_ey]
  192.         jne     CML0
  193.         add     ax,256
  194.         mov     [_ay],ax
  195. CML0:
  196.         ; Calc _t = _a - _e
  197.         mov     ax,[_ax]
  198.         sub     ax,[_ex]
  199.         mov     [_tx],ax
  200.         mov     bx,[_ay]
  201.         sub     bx,[_ey]
  202.         mov     [_ty],bx
  203.         mov     cx,[_az]
  204.         sub     cx,[_ez]
  205.         mov     [_tz],cx
  206.         ; Calc lamdba and |t|
  207.         imul    ax
  208.         mov     di,dx
  209.         mov     si,ax
  210.         mov     ax,bx
  211.         imul    bx
  212.         add     si,ax
  213.         adc     di,dx
  214.         push    di
  215.         push    si
  216.         push    cx
  217.         call    SqRoot
  218.         mov     [lambda],ax
  219.         pop     ax              ; Restore tz
  220.         pop     si              ; Restore lambda
  221.         pop     di              ; ^
  222.         imul    ax
  223.         add     si,ax
  224.         adc     di,dx
  225.         call    SqRoot
  226.         mov     [_t],ax
  227.         ; We got all the needed quantities, calc M1i
  228.         mov     cx,[lambda]
  229.         mov     ax,[_ty]
  230.         cwd
  231.         mov     dl,ah
  232.         mov     ah,al
  233.         xor     al,al
  234.         idiv    cx
  235.         mov     [M11],ax
  236.         mov     ax,[_tx]
  237.         neg     ax
  238.         cwd
  239.         mov     dl,ah
  240.         mov     ah,al
  241.         xor     al,al
  242.         idiv    cx
  243.         mov     [M12],ax
  244.         mov     [M13],0
  245.         ; Now we calc M2i
  246.         mov     bx,[_tz]
  247.         mov     si,[lambda]
  248.         mov     di,[_t]
  249.         ; Calc M21 = tx*tz/(lambda*|t|)
  250.         mov     ax,[_tx]
  251.         imul    bx
  252.         idiv    si
  253.         cwd
  254.         mov     dl,ah
  255.         mov     ah,al
  256.         xor     al,al
  257.         idiv    di
  258.         mov     [M21],ax
  259.         ; Calc M22 = ty*tz/(lambda*|t|)
  260.         mov     ax,[_ty]
  261.         imul    bx
  262.         idiv    si
  263.         cwd
  264.         mov     dl,ah
  265.         mov     ah,al
  266.         xor     al,al
  267.         idiv    di
  268.         mov     [M22],ax
  269.         ; Calc M23 = -lambda/|t|
  270.         mov     ax,si
  271.         neg     ax
  272.         cwd
  273.         mov     dl,ah
  274.         mov     ah,al
  275.         xor     al,al
  276.         idiv    di
  277.         mov     [M23],ax
  278.         ; Now we only have to calc M3i = _t normalized
  279.         ; _tz is in BX and |t| is in DI
  280.         mov     ax,[_tx]
  281.         cwd
  282.         mov     dl,ah
  283.         mov     ah,al
  284.         xor     al,al
  285.         idiv    di
  286.         mov     [M31],ax
  287.         mov     ax,[_ty]
  288.         cwd
  289.         mov     dl,ah
  290.         mov     ah,al
  291.         xor     al,al
  292.         idiv    di
  293.         mov     [M32],ax
  294.         mov     ax,bx           ; _tz
  295.         cwd
  296.         mov     dl,ah
  297.         mov     ah,al
  298.         xor     al,al
  299.         idiv    di
  300.         mov     [M33],ax
  301.         ret
  302. CalcM   ENDP
  303.  
  304. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  305. ;  Function to calc projection plane distance from the FOV [100/sin(FOV/2)]
  306. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  307.         EVEN
  308. CalcDist PROC
  309.         movzx   ebx,[FOV]
  310.         and     bl,0FEh
  311.         mov     bx,SinTbl[ebx]
  312.         mov     ax,100*256              ; Height o'the screen (scaled)
  313.         xor     dx,dx
  314.         div     bx
  315.         mov     [Dist],ax
  316.         ret
  317. CalcDist ENDP
  318.  
  319. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  320. ;  Function to calc 16 bit square root of 32 bit number in DI·SI, ret in AX
  321. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  322. SqRoot  PROC
  323.         xor     dx,dx
  324.         mov     ax,1
  325.         xor     bx,bx
  326.         mov     cx,2
  327. SRML:
  328.         REPT 32
  329.         sub     si,ax
  330.         sbb     di,dx
  331.         jc      SRExit
  332.         add     ax,cx           ; Add 2
  333.         adc     dx,bx           ; Add 0
  334.         ENDM
  335.         jmp     SRML
  336. SRExit: clc
  337.         rcr     dx,1
  338.         rcr     ax,1
  339.         ret
  340. SqRoot  ENDP
  341.  
  342. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  343. ;  Function to calc the points from the camera's reference frame
  344. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  345.         EVEN
  346. WToCam  PROC
  347.         mov     esi,OFFSET WorldPts
  348.         mov     edi,OFFSET CameraPts
  349.         mov     cx,NUM_POINTS
  350. WCML:   ; Calc X coor
  351.         mov     ax,[esi]                ; Get X coor
  352.         sub     ax,[_ex]
  353.         cwd
  354.         imul    [M11]
  355.         mov     bx,ax
  356.         mov     bp,dx
  357.         mov     ax,[esi+2]              ; Get Y coor
  358.         sub     ax,[_ey]
  359.         cwd
  360.         imul    [M12]
  361.         add     bx,ax
  362.         adc     bp,dx
  363.         mov     ax,[esi+4]              ; Get Z coor
  364.         sub     ax,[_ez]
  365.         cwd
  366.         imul    [M13]
  367.         add     ax,bx
  368.         adc     dx,bp
  369.         mov     al,ah
  370.         mov     ah,dl
  371.         stosw                           ; Store X coor tran-ed and rot-ed
  372.         ; Calc Y coor
  373.         mov     ax,[esi]                ; Get X coor
  374.         sub     ax,[_ex]
  375.         cwd
  376.         imul    [M21]
  377.         mov     bx,ax
  378.         mov     bp,dx
  379.         mov     ax,[esi+2]              ; Get Y coor
  380.         sub     ax,[_ey]
  381.         cwd
  382.         imul    [M22]
  383.         add     bx,ax
  384.         adc     bp,dx
  385.         mov     ax,[esi+4]              ; Get Z coor
  386.         sub     ax,[_ez]
  387.         cwd
  388.         imul    [M23]
  389.         add     ax,bx
  390.         adc     dx,bp
  391.         mov     al,ah
  392.         mov     ah,dl
  393.         stosw                           ; Store Y coor tran-ed and rot-ed
  394.         ; Calc Z coor
  395.         mov     ax,[esi]                ; Get X coor
  396.         sub     ax,[_ex]
  397.         cwd
  398.         imul    [M31]
  399.         mov     bx,ax
  400.         mov     bp,dx
  401.         mov     ax,[esi+2]              ; Get Y coor
  402.         sub     ax,[_ey]
  403.         cwd
  404.         imul    [M32]
  405.         add     bx,ax
  406.         adc     bp,dx
  407.         mov     ax,[esi+4]              ; Get Z coor
  408.         sub     ax,[_ez]
  409.         cwd
  410.         imul    [M33]
  411.         add     ax,bx
  412.         adc     dx,bp
  413.         mov     al,ah
  414.         mov     ah,dl
  415.         stosw                           ; Store Z coor tran-ed and rot-ed
  416.         add     esi,6                   ; Next point
  417.         dec     cx
  418.         jz      WCExit                  ; Loop for all world points
  419.         jmp     WCML
  420. WCExit: ret
  421. WToCam  ENDP
  422.  
  423. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  424. ;  Line drawing routine based upon code by Jare/Iguana (AKA Javier Arévalo)
  425. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  426. ; Input: AH is the color, coors are in the following vars
  427. EVEN
  428. MulBy80 LABEL DWORD
  429. I = 0
  430. REPT 200
  431.  DD I*80
  432.  I = I + 1
  433. ENDM
  434. X1      DW ?
  435. X2      DW ?
  436. Y1      DW ?
  437. Y2      DW ?
  438. LVar1   DD 0            ; Increment for DI when there is overflow
  439.         DD 0            ; Inc. for DI when there isn't overflow
  440. AdjDown DD ?            ; Lookup Bresenham's algorithm
  441.         DD 0            ; There isn't AdjDown w/o overflow
  442. RotBits DB ?,?          ; Bits to rot when overflow
  443.         DB ?,?          ; Bits to rot when not overflow
  444.  
  445. LineJmpTblPtr   DD ?
  446.  
  447.         EVEN
  448. DrawLine PROC
  449.         mov     BYTE PTR [ColorByte],ah
  450.         mov     dx,3C4h
  451.         mov     al,2
  452.         out     dx,al                   ; Writes to map mask register
  453.         push    ebp
  454.         push    ecx
  455.         push    esi
  456.         push    edi
  457.         movzx   eax,[Y1]
  458.         movzx   ebx,[Y2]
  459.         movzx   ecx,[X1]
  460.         movzx   esi,[X2]
  461.         cmp     eax,ebx
  462.         jc      LL1
  463.         xchg    ecx,esi
  464.         xchg    eax,ebx
  465. LL1:
  466.         ; (ecx,eax) = upper point (X1,Y1)
  467.         ; (esi,ebx) = the other one (X2,Y2)
  468.         sub     ebx,eax                           ; deltaY
  469.         movzx   edi,[VGASeg]
  470.         shl     edi,4
  471.         mov     edx,eax
  472.         shl     edx,2
  473.         add     edi,MulBy80[edx]
  474.         sub     edi,_code32a
  475.         mov     edx,ecx
  476.         shr     edx,2
  477.         add     edi,edx
  478.         mov     edx,ecx
  479.         and     cl,11b
  480.         mov     al,00010001b
  481.         rol     al,cl
  482.         mov     BYTE PTR [MaskByte],al
  483.         sub     esi,edx                         ; deltaX
  484.         jnc     LL2
  485.         ; arrives here if going from right to left
  486.         neg     esi
  487.         mov     [LineJmpTblPtr],OFFSET LineJmpTbl1
  488.         jmp     LL2B
  489.  
  490. LL2:    ; arrives here if going from left to right
  491.         mov     [LineJmpTblPtr],OFFSET LineJmpTbl2
  492.         ;jmp     LL2B
  493.  
  494. LL2B:   cmp     esi,ebx                         ; cmp deltaX,deltaY
  495.         jnc     LL3
  496.         ; so deltaX < deltaY => non-overflow: dont rot; overflow: rot 1
  497.         mov     [RotBits],1
  498.         mov     [RotBits+2],0
  499.         mov     edx,esi
  500.         xor     esi,esi                         ; Minor inc.
  501.         mov     eax,80                          ; Major inc.
  502.         jmp     LL4
  503.   LL3:  ; so deltaX > deltaY => always rotate
  504.         mov     [RotBits],1
  505.         mov     [RotBits+2],1
  506.         mov     edx,ebx
  507.         mov     ebx,esi
  508.         mov     esi,80                          ; Minor inc.
  509.         xor     eax,eax                         ; Major inc.
  510.   LL4:  mov     ecx,ebx
  511.         or      ecx,ecx
  512.         jz      LExit
  513.   ;LL5:  ; Now: EAX == Major displacement (every pixel does this).
  514.         ;      ESI == Minor (only done when decimal part overflows).
  515.         cmp     [LineJmpTblPtr],OFFSET LineJmpTbl1
  516.         jnz     DontNeg
  517.         neg     eax
  518.         neg     esi
  519. DontNeg:
  520.         add     esi,eax
  521.         mov     [LVar1],esi
  522.         mov     [LVar1+4],eax
  523.         mov     esi,edx
  524.         ; Now:  eax == nothing
  525.         ;       ebx == major axis width
  526.         ;       ecx == major axis width
  527.         ;       esi == minor axis width
  528.         ;       edi == ScreenPtr
  529.         ;       ebp == nothing
  530.         mov     ebp,ebx
  531.         neg     ebp                     ; ebp == -major axis width (to round)
  532.         mov     eax,ebp                 ; eax == -major a.w.
  533.         add     eax,eax                 ; eax *= 2
  534.         mov     [AdjDown],eax
  535.         add     esi,esi                 ; esi == 2*minor a. w. (AdjUp)
  536.         inc     ecx                     ; To draw all the pixels
  537.         mov     ebx,ecx
  538.         mov     eax,ecx
  539.         add     eax,0Fh
  540.         shr     eax,4
  541.         mov     ecx,eax                 ; ecx = # of complete 16 pel groups + 1
  542.         mov     ch,cl                   ; Counter will be CH
  543.         and     ebx,00001111b           ; cx = # of ungrouped pixels
  544.         shl     ebx,2
  545.         mov     dx,3C5h                 ; Writes to map mask register
  546.         mov     ah,0FFh
  547.         ColorByte = $-1
  548.         mov     al,0FFh
  549.         MaskByte = $-1
  550.         add     ebx,[LineJmpTblPtr]
  551.         jmp     DWORD PTR [ebx]
  552.  
  553. LineDumpPixel1 MACRO p
  554. LineLoop1&p:
  555.         out     dx,al                   ; Set map mask register
  556.         mov     BYTE PTR [edi],ah
  557.         add     ebp,esi
  558.         sbb     ebx,ebx
  559.         add     ebx,ebx
  560.         mov     cl,RotBits[ebx+2]
  561.         add     ebx,ebx
  562.         clc
  563.         ror     al,cl
  564.         sbb     edi,LVar1[ebx+4]
  565.         add     ebp,AdjDown[ebx+4]
  566. ENDM
  567.  
  568. LineDumpPixel2 MACRO p
  569. LineLoop2&p:
  570.         out     dx,al                   ; Set map mask register
  571.         mov     BYTE PTR [edi],ah
  572.         add     ebp,esi
  573.         sbb     ebx,ebx
  574.         add     ebx,ebx
  575.         mov     cl,RotBits[ebx+2]
  576.         add     ebx,ebx
  577.         clc
  578.         rol     al,cl
  579.         adc     edi,LVar1[ebx+4]
  580.         add     ebp,AdjDown[ebx+4]
  581. ENDM
  582.  
  583. LineLoop1:
  584.         I = 0
  585.         REPT 16
  586.         LineDumpPixel1 %I
  587.         I = I + 1
  588.         ENDM
  589. EndLineLoop1:
  590.         dec     ch
  591.         jnz     LineLoop1
  592.         jmp     LExit
  593.  
  594. LineLoop2:
  595.         I = 0
  596.         REPT 16
  597.         LineDumpPixel2 %I
  598.         I = I + 1
  599.         ENDM
  600. EndLineLoop2:
  601.         dec     ch
  602.         jnz     LineLoop2
  603.         ;jmp     LExit
  604.  
  605.  
  606. LExit:  pop     edi
  607.         pop     esi
  608.         pop     ecx
  609.         pop     ebp
  610.         ret
  611. DrawLine ENDP
  612.  
  613. EVEN
  614. LineJmpTbl1 LABEL WORD
  615. LineDumpLabel1 MACRO p
  616.         DD OFFSET LineLoop1&p
  617. ENDM
  618.         DD LineLoop10
  619.         I = 15
  620.         REPT 15
  621.          LineDumpLabel1 %I
  622.          I = I - 1
  623.         ENDM
  624.  
  625. LineJmpTbl2 LABEL WORD
  626. LineDumpLabel2 MACRO p
  627.         DD OFFSET LineLoop2&p
  628. ENDM
  629.         DD LineLoop20
  630.         I = 15
  631.         REPT 15
  632.          LineDumpLabel2 %I
  633.          I = I - 1
  634.         ENDM
  635.  
  636. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  637. ;  Function to erase all the lines of the previous frame
  638. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  639.         EVEN
  640. EraseBufferedLines PROC
  641.         mov     esi,[NumBufferedLinesPtr]
  642.         mov     cx,[esi]
  643.         or      cx,cx
  644.         jz      EBLExit
  645.         mov     esi,[LinesBufferPtr]
  646. EBLML:  push    cx
  647.         mov     ax,[esi]
  648.         mov     [X1],ax
  649.         mov     ax,[esi+2]
  650.         mov     [Y1],ax
  651.         mov     ax,[esi+4]
  652.         mov     [X2],ax
  653.         mov     ax,[esi+6]
  654.         mov     [Y2],ax
  655.         xor     ah,ah
  656.         push    esi
  657.         call    DrawLine
  658.         pop     esi
  659.         add     esi,8
  660.         pop     cx
  661.         dec     cx
  662.         jnz     EBLMl
  663.         mov     esi,[NumBufferedLinesPtr]
  664.         mov     WORD PTR [esi],0
  665. EBLExit:
  666.         ret
  667. EraseBufferedLines ENDP
  668.  
  669. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  670. ;  Function to erase all the polygons of the previous frame
  671. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  672.         EVEN
  673. EraseBufferedPolys PROC
  674.         xor     al,al                           ; Erase with black!
  675.         mov     esi,[LinesBufferPtr]
  676.         call    DumpPBuf
  677.         mov     edi,[LinesBufferPtr]
  678.         call    ClearPBuf
  679.         ret
  680.  
  681. EraseBufferedPolys ENDP
  682.  
  683. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  684. ;  Function to draw the things in wireframe
  685. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  686. EVEN
  687. DWX DW ?
  688. DWY DW ?
  689. DWZ DW ?
  690. DWClr   DB ?
  691.  
  692.         EVEN
  693. DrawWire PROC
  694.         mov     esi,[SortedFacetsHeadPtr]
  695.         or      esi,esi
  696.         jz      _ret
  697. DWML0:  push    esi
  698.         mov     esi,[esi+8]             ; Get effective facet data ptr
  699.         mov     cx,[esi+6]              ; Get # of points
  700.         dec     cx                      ; Loop for # of pts - 1
  701.         mov     al,BYTE PTR [esi+2]     ; Get color
  702.         mov     [DWClr],al
  703.         add     esi,8                   ; Skip facet header
  704.         mov     ax,[esi]
  705.         mov     [DWX],ax
  706.         push    ax
  707.         mov     ax,[esi+2]
  708.         mov     [DWY],ax
  709.         push    ax
  710.         mov     ax,[esi+4]
  711.         mov     [DWZ],ax
  712.         push    ax
  713.         add     esi,6                   ; Skip 1st pt
  714. DWML1:  mov     ax,[DWX]                ; Don't load again
  715.         mov     [L3DX1],ax
  716.         mov     ax,[DWY]
  717.         mov     [L3DY1],ax
  718.         mov     ax,[DWZ]
  719.         mov     [L3DZ1],ax
  720.         mov     ax,[esi]
  721.         mov     [L3DX2],ax
  722.         mov     [DWX],ax
  723.         mov     ax,[esi+2]
  724.         mov     [L3DY2],ax
  725.         mov     [DWY],ax
  726.         mov     ax,[esi+4]
  727.         mov     [L3DZ2],ax
  728.         mov     [DWZ],ax
  729.         mov     ah,[DWClr]
  730.         push    esi
  731.         push    cx
  732.         call    Draw3DLine
  733.         pop     cx
  734.         pop     esi
  735.         add     esi,6                    ; Skip point
  736.         dec     cx
  737.         jnz     DWML1
  738.         ; Now, we gotta draw the last line
  739.         pop     [L3DZ2]
  740.         pop     [L3DY2]
  741.         pop     [L3DX2]
  742.         mov     ax,[DWX]
  743.         mov     [L3DX1],ax
  744.         mov     ax,[DWY]
  745.         mov     [L3DY1],ax
  746.         mov     ax,[DWZ]
  747.         mov     [L3DZ1],ax
  748.         mov     ah,[DWClr]
  749.         call    Draw3DLine
  750.         pop     esi                     ; Restore ptr to the linked list
  751.         mov     esi,[esi]
  752.         or      esi,esi
  753.         jnz     DWML0
  754.         ret
  755. DrawWire ENDP
  756.  
  757. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  758. ;  Function to draw the things solid!
  759. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  760.         EVEN
  761. DSOPBuf DW 200 DUP (?,?)
  762. DSOX    DW ?
  763. DSOY    DW ?
  764. DSOZ    DW ?
  765. DSOClr  DB ?
  766.  
  767.         EVEN
  768. DrawSolid PROC
  769.         mov     esi,[SortedFacetsHeadPtr]
  770.         or      esi,esi
  771.         jz      _ret
  772. DSOML0: push    esi
  773.         mov     edi,OFFSET DSOPBuf
  774.         call    ClearPBuf
  775.         mov     esi,[esp]
  776.         mov     esi,[esi+8]             ; Get effective facet data ptr
  777.         mov     cx,[esi+6]              ; Get # of points
  778.         dec     cx                      ; Loop for # of pts - 1
  779.         mov     al,BYTE PTR [esi+2]     ; Get color
  780.         mov     [DSOClr],al
  781.         add     esi,8                   ; Skip facet header
  782.         mov     ax,[esi]
  783.         mov     [DSOX],ax
  784.         push    ax
  785.         mov     ax,[esi+2]
  786.         mov     [DSOY],ax
  787.         push    ax
  788.         mov     ax,[esi+4]
  789.         mov     [DSOZ],ax
  790.         push    ax
  791.         add     esi,6                   ; Skip 1st pt
  792. DSOML1: mov     ax,[DSOX]               ; Don't load again
  793.         mov     [A3DX1],ax
  794.         mov     ax,[DSOY]
  795.         mov     [A3DY1],ax
  796.         mov     ax,[DSOZ]
  797.         mov     [A3DZ1],ax
  798.         mov     ax,[esi]
  799.         mov     [A3DX2],ax
  800.         mov     [DSOX],ax
  801.         mov     ax,[esi+2]
  802.         mov     [A3DY2],ax
  803.         mov     [DSOY],ax
  804.         mov     ax,[esi+4]
  805.         mov     [A3DZ2],ax
  806.         mov     [DSOZ],ax
  807.         mov     edi,OFFSET DSOPBuf
  808.         push    esi
  809.         push    cx
  810.         call    Add3DLine
  811.         pop     cx
  812.         pop     esi
  813.         add     esi,6                   ; Skip point
  814.         dec     cx
  815.         jnz     DSOML1
  816.         ; Now, we gotta draw the last line
  817.         pop     [A3DZ2]
  818.         pop     [A3DY2]
  819.         pop     [A3DX2]
  820.         mov     ax,[DSOX]
  821.         mov     [A3DX1],ax
  822.         mov     ax,[DSOY]
  823.         mov     [A3DY1],ax
  824.         mov     ax,[DSOZ]
  825.         mov     [A3DZ1],ax
  826.         mov     edi,OFFSET DSOPBuf
  827.         call    Add3DLine
  828.  
  829.         ; Now dump the polygon to screen
  830.         mov     esi,OFFSET DSOPBuf
  831.         mov     al,[DSOClr]
  832.         call    DumpPBuf
  833.  
  834.         ; Now buffer the polygon for latter erasing
  835.         mov     esi,OFFSET DSOPBuf
  836.         mov     edi,[LinesBufferPtr]
  837.         call    AddPBuf
  838.  
  839.         ; Keep on with other polygons
  840.         pop     esi                     ; Restore ptr to the linked list
  841.         mov     esi,[esi]
  842.         or      esi,esi
  843.         jnz     DSOML0
  844.         ret
  845. DrawSolid ENDP
  846.  
  847. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  848. ;  Function to draw the 2D projection of a 3D line
  849. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  850.         EVEN
  851. L3DX1   DW ?
  852. L3DY1   DW ?
  853. L3DZ1   DW ?
  854. L3DX2   DW ?
  855. L3DY2   DW ?
  856. L3DZ2   DW ?
  857. D3DLColor   DB ?
  858.         EVEN
  859. Draw3DLine PROC
  860.         mov     [D3DLColor],ah
  861.         mov     di,[L3DZ1]              ; Get Z coor
  862.         mov     ax,[L3DX1]              ; Get X coor
  863.         imul    [Dist]
  864.         idiv    di                      ; X' = X * Dist / Z
  865.         add     ax,160                  ; To center in screen
  866.         mov     [X1],ax
  867.         mov     ax,[L3DY1]              ; Get Y coor
  868.         imul    [Dist]
  869.         idiv    di                      ; Y' = Y * Dist / Z
  870.         add     ax,100
  871.         mov     [Y1],ax
  872.         mov     di,[L3DZ2]              ; Get Z coor
  873.         mov     ax,[L3DX2]              ; Get X coor
  874.         imul    [Dist]
  875.         idiv    di                      ; X' = X * Dist / Z
  876.         add     ax,160                  ; To center in screen
  877.         mov     [X2],ax
  878.         mov     ax,[L3DY2]              ; Get Y coor
  879.         imul    [Dist]
  880.         idiv    di                      ; Y' = Y * Dist / Z
  881.         add     ax,100
  882.         mov     [Y2],ax
  883.         ; Clip the line in (X1,Y1)-(X2,Y2)
  884.         call    ClipLine
  885.         jc      D3DLL0  ; Completely invisible
  886.         ; Buffer the line for later erasing:
  887.         mov     esi,[NumBufferedLinesPtr]
  888.         movzx   esi,WORD PTR [esi]
  889.         shl     esi,3                   ; 8 bytes per buf. line
  890.         add     esi,[LinesBufferPtr]
  891.         mov     ax,[X1]
  892.         mov     [esi],ax
  893.         mov     ax,[Y1]
  894.         mov     [esi+2],ax
  895.         mov     ax,[X2]
  896.         mov     [esi+4],ax
  897.         mov     ax,[Y2]
  898.         mov     [esi+6],ax
  899.         mov     esi,[NumBufferedLinesPtr]
  900.         inc     WORD PTR [esi]
  901.         ; Draw the line without clipping:
  902.         mov     ah,[D3DLColor]
  903.         call    DrawLine
  904. D3DLL0:
  905.         ret
  906. Draw3DLine ENDP
  907.  
  908. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  909. ;  Function to add the 2D projection of a 3D line to a polygon buffer
  910. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  911. ; EDI -> Polygon buffer
  912.         EVEN
  913. A3DX1   DW ?
  914. A3DY1   DW ?
  915. A3DZ1   DW ?
  916. A3DX2   DW ?
  917. A3DY2   DW ?
  918. A3DZ2   DW ?
  919. A3DLPBuf DD ?
  920.  
  921.         EVEN
  922. Add3DLine PROC
  923.         mov     [A3DLPBuf],edi
  924.         mov     di,[A3DZ1]              ; Get Z coor
  925.         mov     ax,[A3DX1]              ; Get X coor
  926.         imul    [Dist]
  927.         idiv    di                      ; X' = X * Dist / Z
  928.         add     ax,160                  ; To center in screen
  929.         mov     [ALPBX1],ax
  930.         mov     ax,[A3DY1]              ; Get Y coor
  931.         imul    [Dist]
  932.         idiv    di                      ; Y' = Y * Dist / Z
  933.         add     ax,100
  934.         mov     [ALPBY1],ax
  935.         mov     di,[A3DZ2]              ; Get Z coor
  936.         mov     ax,[A3DX2]              ; Get X coor
  937.         imul    [Dist]
  938.         idiv    di                      ; X' = X * Dist / Z
  939.         add     ax,160                  ; To center in screen
  940.         mov     [ALPBX2],ax
  941.         mov     ax,[A3DY2]              ; Get Y coor
  942.         imul    [Dist]
  943.         idiv    di                      ; Y' = Y * Dist / Z
  944.         add     ax,100
  945.         mov     [ALPBY2],ax
  946.         ; Clip the line in ALPB (X1,Y1)-(X2,Y2)
  947.         call    ClipVLine
  948.         jc      A3DLL0  ; Completely outside
  949.         ; Add the line without further clipping:
  950.         mov     edi,[A3DLPBuf]
  951.         call    AddLineToPBuf
  952. A3DLL0:
  953.         ret
  954. Add3DLine ENDP
  955.  
  956. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  957. ;  Function to build new facets clipping against Z = ZN
  958. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  959. EVEN
  960. LastPoint       DW ?
  961. VertCounter     DW ?
  962.  
  963.         EVEN
  964. BuildClip PROC
  965.         mov     ebp,OFFSET ClippedFacetsBuffer
  966.         mov     esi,OFFSET Facets
  967.         mov     [NumFacets],0
  968.         mov     cx,NUM_FACETS
  969.  
  970.    ; Loops for all the facets in the scene
  971.  
  972. BCML0:  push    cx      ; Save facet counter
  973.         mov     edi,ebp
  974.         movsw              ; Copy facet type
  975.         movsw              ; Copy facet data lo
  976.         movsw              ; Copy facet data hi
  977.         xor     eax,eax
  978.         stosw   ; Initially 0 points in clipped facet
  979.         lodsw   ; Get # of points before clipping
  980.         mov     [VertCounter],ax
  981.         mov     ebx,eax
  982.         add     ebx,ebx    ; # of bytes to the last point
  983.         movzx   ebx,WORD PTR [esi+ebx-2]
  984.         mov     [LastPoint],bx   ; Keep inx of the last point
  985.         mov     eax,ebx    ; \
  986.         add     ebx,ebx    ; \
  987.         add     ebx,eax    ; \
  988.         add     ebx,ebx    ; ebx = 6 * inx
  989.         mov     dx,[ZN]
  990.         xor     cl,cl      ; The flag
  991.         cmp     CameraPts[ebx+4],dx  ; CMP Zlast,ZN
  992.         jl      BCML1
  993.         inc     cl
  994.  
  995.    ; Loops for all the vertices in the facet
  996.  
  997. BCML1:  movzx  ebx,WORD PTR [esi]
  998.         mov    eax,ebx     ; \
  999.         add    ebx,ebx     ; \
  1000.         add    ebx,eax     ; \
  1001.         add    ebx,ebx     ; bx =  6 * inx
  1002.         add    ebx,OFFSET CameraPts
  1003.         mov    ax,[ebx+4]
  1004.         mov    dx,[ZN]
  1005.         xor    ch,ch
  1006.         cmp    ax,dx
  1007.         jl     BCL0
  1008.         inc    ch
  1009.   BCL0: xor    cl,ch
  1010.         jz     BCL1        ; If both on the same side, needn't clip
  1011.         push   cx
  1012.         push   esi
  1013.         push   ebp
  1014.         movzx  esi,WORD PTR [LastPoint]
  1015.         mov    ecx,esi     ; \
  1016.         add    esi,esi     ; \
  1017.         add    esi,ecx     ; \
  1018.         add    esi,esi     ; si = 6 * inx
  1019.         add    esi,OFFSET CameraPts
  1020.         mov    cx,[ZN]
  1021.         sub    cx,ax
  1022.         jns    BCL2
  1023.         neg    cx
  1024.   BCL2: sub    ax,[esi+4]
  1025.         jns    BCL3
  1026.         neg    ax
  1027.   BCL3: mov    bp,ax
  1028.         mov    ax,[esi]    ; Get X1
  1029.         sub    ax,[ebx]    ; AX = (X1-X0)
  1030.         imul   cx          ; AX = (ZN-Z0).(X1-X0)
  1031.         idiv   bp          ; AX = (ZN-Z0).(X1-X0)/(Z1-Z0)
  1032.         add    ax,[ebx]    ; AX += X0
  1033.         stosw
  1034.         mov    ax,[esi+2]  ; Get Y1
  1035.         sub    ax,[ebx+2]  ; AX = (Y1-Y0)
  1036.         imul   cx          ; AX = (ZN-Z0).(Y1-Y0)
  1037.         idiv   bp          ; AX = (ZN-Z0).(Y1-Y0)/(Z1-Z0)
  1038.         add    ax,[ebx+2]  ; AX += Y0
  1039.         stosw
  1040.         mov    ax,[ZN]
  1041.         stosw
  1042.         pop    ebp
  1043.         pop    esi
  1044.         pop    cx
  1045.         inc    WORD PTR [ebp+6]  ; One more point in clipped facet ptlist
  1046.   BCL1: mov    cl,ch
  1047.         or     cl,cl
  1048.         jz     BCL4
  1049.         mov    ax,[ebx]
  1050.         stosw
  1051.         mov    ax,[ebx+2]
  1052.         stosw
  1053.         mov    ax,[ebx+4]
  1054.         stosw
  1055.         inc    WORD PTR [ebp+6]  ; 1 more point ...
  1056.   BCL4: lodsw
  1057.         mov    [LastPoint],ax
  1058.         dec    [VertCounter]
  1059.         jnz     BCML1
  1060.  
  1061.         cmp    WORD PTR [ebp+6],0
  1062.         je     BCL5
  1063.         mov    ebp,edi
  1064.         inc    [NumFacets]
  1065.   BCL5: pop    cx
  1066.         dec    cx
  1067.         jnz    BCML0
  1068.  
  1069.         ret
  1070.  
  1071. BuildClip ENDP
  1072.  
  1073. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1074. ;  Function to clear the screen (just 1st page)
  1075. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1076.         EVEN
  1077. ClrScr  PROC
  1078.         mov     dx,3C4h
  1079.         mov     ax,0F02h                ; Map Mask register = 1111b
  1080.         out     dx,ax
  1081.         movzx   edi,[VGASeg]
  1082.         shl     edi,4
  1083.         sub     edi,_code32a
  1084.         xor     eax,eax                 ; Fill with zeros
  1085.         mov     ecx,4096d               ; Words in first page
  1086.         rep     stosd
  1087.         ret
  1088. ClrScr  ENDP
  1089.  
  1090. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1091. ;  Function to clip the line defined by (X1,Y1)-(X2,Y2) to the 320x200 rect
  1092. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1093. ; We use the familiar Cohen-Sutherland algorithm:
  1094. ;
  1095. ;    1001 | 1000 | 1010
  1096. ;    ------------------
  1097. ;    0001 | 0000 | 0010
  1098. ;    ------------------
  1099. ;    0101 | 0100 | 0110
  1100. ;
  1101.         EVEN
  1102. ClipLine PROC
  1103.         ; In CL and CH we calc the codes for P1 and P2
  1104.         mov     bx,[X1]
  1105.         mov     bp,[X2]
  1106.         mov     si,[Y1]
  1107.         mov     di,[Y2]
  1108. CLAgain:
  1109.         xor     cl,cl           ; Code for P1
  1110.         or      bx,bx
  1111.         jns     CL0
  1112.         or      cl,0001b
  1113. CL0:    cmp     bx,320
  1114.         jl      CL1
  1115.         or      cl,0010b
  1116. CL1:    or      si,si
  1117.         jns     CL2
  1118.         or      cl,1000b
  1119. CL2:    cmp     si,200
  1120.         jl      CL3
  1121.         or      cl,0100b
  1122. CL3:    xor     ch,ch           ; Code for P2
  1123.         or      bp,bp
  1124.         jns     CL4
  1125.         or      ch,0001b
  1126. CL4:    cmp     bp,320
  1127.         jl      CL5
  1128.         or      ch,0010b
  1129. CL5:    or      di,di
  1130.         jns     CL6
  1131.         or      ch,1000b
  1132. CL6:    cmp     di,200
  1133.         jl      CL7
  1134.         or      ch,0100b
  1135. CL7:
  1136.         ; Now, we have: CL=P1 code, CH=P2 code, BX=X1, BP=X2, SI=Y1, DI=Y2
  1137.         mov     al,cl
  1138.         or      al,ch
  1139.         jnz     CL8
  1140.         ; Both segments are inside the screen
  1141.         jmp     CLExit
  1142. CL8:    test    cl,ch
  1143.         jz      CL9
  1144.         ; Both segments are outside on the same side
  1145.         stc                     ; Don't draw
  1146.         ret
  1147. CL9:    xor     cl,ch
  1148.         cmp     si,di           ; Make sure Y1 < Y2
  1149.         jle     CL10
  1150.         xchg    si,di
  1151.         xchg    bx,bp
  1152. CL10:
  1153.         test    cl,1000b        ; Have to cut against Y=0 ?
  1154.         jz      CL11
  1155.         ; Cut against Y=0
  1156.         push    di
  1157.         sub     bx,bp
  1158.         mov     ax,bx
  1159.         imul    di
  1160.         sub     di,si
  1161.         idiv    di
  1162.         add     ax,bp           ; NewX1 = X2+(X1-X2)*Y2/(Y2-Y1)
  1163.         mov     bx,ax           ; NewX1 = ^^^^^^^^^^^^^^^^^^^^^
  1164.         xor     si,si           ; NewY1 = 0
  1165.         pop     di
  1166.         jmp     CLAgain
  1167. CL11:   test    cl,0100b
  1168.         jz      CL12
  1169.         ; Cut against Y=199
  1170.         push    si
  1171.         sub     si,199
  1172.         sub     di,199
  1173.         ; Cutting against 0
  1174.         sub     bp,bx
  1175.         mov     ax,bp
  1176.         imul    si
  1177.         sub     si,di
  1178.         idiv    si
  1179.         add     ax,bx           ; NewX2 = X1+(X2-X1)*Y1/(Y1-Y2)
  1180.         mov     bp,ax
  1181.         mov     di,199          ; NewY2 = 199
  1182.         pop     si              ; NewY1 = OldY1
  1183.         jmp     CLAgain
  1184. CL12:   cmp     bx,bp           ; Make sure X1 < X2
  1185.         jle     CL15
  1186.         xchg    si,di
  1187.         xchg    bx,bp
  1188. CL15:   test    cl,0001b        ; Have to cut against X=0 ?
  1189.         jz      CL13
  1190.         ; Cut against X=0
  1191.         push    bp
  1192.         sub     si,di
  1193.         mov     ax,si
  1194.         imul    bp
  1195.         sub     bp,bx
  1196.         idiv    bp
  1197.         add     ax,di           ; NewY1 = Y2+(Y1-Y2)*X2/(X2-X1)
  1198.         mov     si,ax           ; NewY1 = ^^^^^^^^^^^^^^^^^^^^^
  1199.         xor     bx,bx           ; NewX1 = 0
  1200.         pop     bp
  1201.         jmp     CLAgain
  1202. CL13:   test    cl,0010b
  1203.         jz      CLExit
  1204.         ; Cut against X=319
  1205.         push    bx
  1206.         sub     bx,319
  1207.         sub     bp,319
  1208.         ; Cutting against 0
  1209.         sub     di,si
  1210.         mov     ax,di
  1211.         imul    bx
  1212.         sub     bx,bp
  1213.         idiv    bx
  1214.         add     ax,si           ; NewY2 = Y1+(Y2-Y1)*X1/(X1-X2)
  1215.         mov     di,ax
  1216.         mov     bp,319          ; NewX2 = 319
  1217.         pop     bx              ; NewY1 = OldY1
  1218.         jmp     CLAgain
  1219. CLExit: ; We've passed all the clippings
  1220.         mov     [X1],bx
  1221.         mov     [X2],bp
  1222.         mov     [Y1],si
  1223.         mov     [Y2],di
  1224.         clc                     ; Visible
  1225.         ret
  1226. ClipLine ENDP
  1227.  
  1228. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1229. ;  Function to clip line defined by ALPB (X1,Y1)-(X2,Y2) to the INFx200 rect
  1230. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1231. ; We use a variation of the familiar Cohen-Sutherland algorithm:
  1232. ;
  1233. ;     10
  1234. ;    ----
  1235. ;     00
  1236. ;    ----
  1237. ;     01
  1238. ;
  1239.         EVEN
  1240. ClipVLine PROC
  1241.         ; In CL and CH we calc the codes for P1 and P2
  1242.         mov     bx,[ALPBX1]
  1243.         mov     bp,[ALPBX2]
  1244.         mov     si,[ALPBY1]
  1245.         mov     di,[ALPBY2]
  1246. CVLAgain:
  1247.         xor     cl,cl           ; Code for P1
  1248.         or      si,si
  1249.         jns     CVL2
  1250.         or      cl,10b
  1251. CVL2:   cmp     si,200
  1252.         jl      CVL3
  1253.         or      cl,01b
  1254. CVL3:   xor     ch,ch           ; Code for P2
  1255.         or      di,di
  1256.         jns     CVL6
  1257.         or      ch,10b
  1258. CVL6:   cmp     di,200
  1259.         jl      CVL7
  1260.         or      ch,01b
  1261. CVL7:
  1262.         ; Now, we have: CL=P1 code, CH=P2 code, BX=X1, BP=X2, SI=Y1, DI=Y2
  1263.         mov     al,cl
  1264.         or      al,ch
  1265.         jnz     CVL8
  1266.         ; Both segments are inside the rectangle
  1267.         jmp     CVLExit
  1268. CVL8:   test    cl,ch
  1269.         jz      CVL9
  1270.         ; Both segments are outside on the same side
  1271.         stc                     ; Don't draw
  1272.         ret
  1273. CVL9:   xor     cl,ch
  1274.         cmp     si,di           ; Make sure Y1 < Y2
  1275.         jle     CVL10
  1276.         xchg    si,di
  1277.         xchg    bx,bp
  1278. CVL10:
  1279.         test    cl,10b        ; Have to cut against Y=0 ?
  1280.         jz      CVL11
  1281.         ; Cut against Y=0
  1282.         push    di
  1283.         sub     bx,bp
  1284.         mov     ax,bx
  1285.         imul    di
  1286.         sub     di,si
  1287.         idiv    di
  1288.         add     ax,bp           ; NewX1 = X2+(X1-X2)*Y2/(Y2-Y1)
  1289.         mov     bx,ax           ; NewX1 = ^^^^^^^^^^^^^^^^^^^^^
  1290.         xor     si,si           ; NewY1 = 0
  1291.         pop     di
  1292.         jmp     CVLAgain
  1293. CVL11:  test    cl,01b
  1294.         jz      CVLExit
  1295.         ; Cut against Y=199
  1296.         push    si
  1297.         sub     si,199
  1298.         sub     di,199
  1299.         ; Cutting against 0
  1300.         sub     bp,bx
  1301.         mov     ax,bp
  1302.         imul    si
  1303.         sub     si,di
  1304.         idiv    si
  1305.         add     ax,bx           ; NewX2 = X1+(X2-X1)*Y1/(Y1-Y2)
  1306.         mov     bp,ax
  1307.         mov     di,199          ; NewY2 = 199
  1308.         pop     si              ; NewY1 = OldY1
  1309.         jmp     CVLAgain
  1310. CVLExit: ; We've passed all the clippings
  1311.         mov     [ALPBX1],bx
  1312.         mov     [ALPBX2],bp
  1313.         mov     [ALPBY1],si
  1314.         mov     [ALPBY2],di
  1315.         clc                     ; Visible
  1316.         ret
  1317. ClipVLine ENDP
  1318.  
  1319. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1320. ;  Function to sort the facets in back-to-front order for the painter's alg.
  1321. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1322. EVEN
  1323. Averages DW ?,?,?
  1324. CoorsCounter DW ?
  1325. ThisFacetPtr DD ?
  1326. NextFacetPtr DD ?
  1327.  
  1328.         EVEN
  1329. SortByDist PROC
  1330.         mov     [SortedFacetsHeadPtr],0
  1331.         mov     esi,OFFSET ClippedFacetsBuffer
  1332.         mov     cx,[NumFacets]
  1333.         or      cx,cx
  1334.         jz      SDExit
  1335.         mov     [NextFreeSlotPtr],OFFSET SortedFacetsList
  1336.         mov     [SortedFacetsHeadPtr],0
  1337. SDML:   push    cx
  1338.         mov     cx,[esi+6]              ; Get # of pts in the facet
  1339.         mov     [ThisFacetPtr],esi
  1340.         add     esi,8                   ; To point to the coors
  1341.         mov     [CoorsCounter],6
  1342. SDL0:   push    esi
  1343.         push    cx                      ; Keep # of points
  1344.         xor     dx,dx
  1345.         xor     ax,ax
  1346. SDL1:   mov     bx,[esi]
  1347.         or      bx,bx
  1348.         jns     SDL4
  1349.         neg     bx
  1350.         sub     ax,bx
  1351.         sbb     dx,0
  1352.         add     esi,6                   ; To coor i of next point
  1353.         dec     cx
  1354.         jnz     SDL1
  1355.         jmp     SDL5
  1356. SDL4:   add     ax,bx
  1357.         adc     dx,0
  1358.         add     esi,6
  1359.         dec     cx
  1360.         jnz     SDL1
  1361. SDL5:   sub     esi,4                   ; When looping on coors Z, it will
  1362.                                         ; store the pointer to next facet0
  1363.         mov     [NextFacetPtr],esi
  1364.         pop     cx                      ; Restore # of points
  1365.         pop     esi
  1366.         add     esi,2                   ; Switch to next coor
  1367.         idiv    cx                      ; Calc average
  1368.         movzx   ebx,WORD PTR [CoorsCounter]
  1369.         neg     ebx
  1370.         add     ebx,6
  1371.         mov     Averages[ebx],ax
  1372.         sub     [CoorsCounter],2
  1373.         jnz     SDL0
  1374.         mov     ax,[Averages]           ; Get average X coor
  1375.         imul    ax
  1376.         mov     di,dx
  1377.         mov     cx,ax
  1378.         mov     ax,[Averages+2]         ; Get average Y coor
  1379.         imul    ax
  1380.         add     cx,ax
  1381.         adc     di,dx
  1382.         mov     ax,[Averages+4]         ; Get average Z coor
  1383.         imul    ax
  1384.         add     cx,ax
  1385.         adc     di,dx
  1386.         ; Now we have x^2+y^2+z^2 in DI·CX, insert into the sorted list
  1387.         mov     ebx,[NextFreeSlotPtr]
  1388.         mov     [ebx+4],cx
  1389.         mov     [ebx+6],di
  1390.         mov     eax,[ThisFacetPtr]
  1391.         mov     [ebx+8],ax
  1392.         ; Do the loop to insert
  1393.         mov     ebx,OFFSET SortedFacetsHeadPtr
  1394. SDL2:   mov     esi,[ebx]               ; Get address of next facet item
  1395.         or      esi,esi
  1396.         jz      SDDoInsert
  1397.         cmp     di,[esi+6]              ; CMP ThisHiDist,ThatHiDist
  1398.         jg      SDDoInsert
  1399.         jl      SDGotoNext
  1400.         cmp     cx,[esi+4]
  1401.         jge     SDDoInsert
  1402. SDGotoNext:
  1403.         mov     ebx,esi
  1404.         jmp     SDL2
  1405. SDDoInsert:
  1406.         ; Here, bx points to the Next ptr to alter, [ebx] is the Next
  1407.         ;  field to put in our Next field
  1408.         mov     esi,[NextFreeSlotPtr]
  1409.         mov     eax,[ebx]
  1410.         mov     [esi],eax               ; Set our Next field to insert
  1411.         mov     [ebx],esi               ; Alter the Next field
  1412.         add     esi,12
  1413.         mov     [NextFreeSlotPtr],esi   ; Update NextFreeSlot
  1414.         ; Continue the loop
  1415.         mov     esi,[NextFacetPtr]
  1416.         pop     cx                      ; Restore # of facets
  1417.         dec     cx
  1418.         jz      SDExit
  1419.         jmp     SDML
  1420. SDExit:
  1421.         ret
  1422. SortByDist ENDP
  1423.  
  1424. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1425. ;  Function to sequence the animation
  1426. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1427. TAGSIZE = 2 + 2*14      ; Tag id plus 14 words
  1428. NextTag DD OFFSET Movement
  1429. DSFramesLeft DW 0
  1430. DSStart DW 6 DUP(?)     ; Starting _ex,_ey,_ez,_ax,_ay,_az
  1431. DSEnd   DW 6 DUP(?)     ; Ending    "
  1432. DSCrnt  DW 6 DUP(?)     ; Current value
  1433. DSIntA  DW 6 DUP(?)     ; Integer advance (done always)
  1434. DSFracA DW 6 DUP(?)     ; Fractional advance (only when carry)
  1435. DSFrac  DW 6 DUP(?)     ; Current fractional part
  1436. DSAdjU  DW 6 DUP(?)     ; Adjust fractional part
  1437. DSAdjD  DW 6 DUP(?)     ; Only when carry, substract this
  1438.  
  1439.         EVEN
  1440. DoSeq   PROC
  1441.         mov     ax,[DSFramesLeft]
  1442.         or      ax,ax
  1443.         jz      DSInitTag
  1444.         jmp     DSNrmSeq
  1445. DSInitTag:
  1446.         ; So we have to setup the Bres data for the new sequence tag
  1447.         mov     esi,[NextTag]
  1448.         add     [NextTag],TAGSIZE
  1449.         mov     ax,[esi]
  1450.         inc     ax
  1451.         jnz     DSL0
  1452.         mov     [QuitPrg],1
  1453.         ret
  1454. DSL0:   ; So it's definitely a brand new animation tag
  1455.         inc     esi
  1456.         inc     esi
  1457.         mov     edi,OFFSET DSStart
  1458.         mov     cx,12
  1459.         rep movsw               ; Get starting and ending coordinates
  1460.         lodsw                   ; Get the FOV
  1461.         mov     [FOV],ax
  1462.         lodsw                   ; Get the # of frames for this tag
  1463.         mov     [DSFramesLeft],ax
  1464.         cmp     ax,1
  1465.         jne     DSL4
  1466.         ; Needn't do a Bres 'cos it's just one frame
  1467.         mov     esi,OFFSET DSStart
  1468.         mov     edi,OFFSET DSCrnt
  1469.         mov     cx,6
  1470.         rep movsw
  1471.         jmp     DSTransfer
  1472. DSL4:   mov     bp,ax           ; Keep in BP the # of frames, during the MLoop
  1473.         mov     esi,10          ; Start calculating from the last of the 6
  1474. DSML0:  mov     bx,DSStart[esi]
  1475.         mov     DSCrnt[esi],bx
  1476.         mov     ax,DSEnd[esi]
  1477.         sub     ax,bx           ; AX is the total delta
  1478.         mov     cx,1
  1479.         jns     DSL2
  1480.         neg     cx
  1481. DSL2:   mov     DSFracA[esi],cx
  1482.         cwd
  1483.         idiv    bp              ; Divide by the # of frames
  1484.         mov     DSIntA[esi],ax  ; Integral advance
  1485.         or      dx,dx
  1486.         jns     DSL3
  1487.         neg     dx
  1488. DSL3:   add     dx,dx           ; DX = 2 * dQuant
  1489.         mov     DSAdjU[esi],dx
  1490.         mov     ax,bp
  1491.         neg     ax
  1492.         mov     DSFrac[esi],ax
  1493.         mov     ax,bp
  1494.         add     ax,ax
  1495.         mov     DSAdjD[esi],ax
  1496.         sub     esi,1
  1497.         jc      DSTransfer
  1498.         dec     esi
  1499.         jmp     DSML0
  1500.  
  1501. DSNrmSeq:                       ; Advance the Bresenhams
  1502.         mov     esi,10
  1503. DSML1:  mov     ax,DSCrnt[esi]
  1504.         mov     bx,DSFrac[esi]
  1505.         add     ax,DSIntA[esi]
  1506.         add     bx,DSAdjU[esi]
  1507.         jnc     DSL1
  1508.         sub     bx,DSAdjD[esi]
  1509.         add     ax,DSFracA[esi]
  1510. DSL1:   mov     DSCrnt[esi],ax
  1511.         mov     DSFrac[esi],bx
  1512.         sub     esi,1
  1513.         jc      DSTransfer
  1514.         dec     esi
  1515.         jmp     DSML1
  1516.  
  1517. DSTransfer:                     ; Transfer to _e and _a
  1518.         mov     esi,OFFSET DSCrnt
  1519.         lodsw
  1520.         mov     [_ex],ax
  1521.         lodsw
  1522.         mov     [_ey],ax
  1523.         lodsw
  1524.         mov     [_ez],ax
  1525.         lodsw
  1526.         mov     [_ax],ax
  1527.         lodsw
  1528.         mov     [_ay],ax
  1529.         lodsw
  1530.         mov     [_az],ax
  1531.  
  1532.         dec     [DSFramesLeft]
  1533.         ret
  1534. DoSeq   ENDP
  1535.  
  1536. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1537. ;  Function to clear a polygon buffer 
  1538. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1539. ; IN: EDI -> Polygon buffer
  1540.         EVEN
  1541. ClearPBuf PROC
  1542.         mov     WORD PTR [edi],7FFFh     ; Maximum X coor (32767)
  1543.         mov     WORD PTR [edi+2],8000h   ; Minimum X coor (-32768)
  1544.         mov     esi,edi
  1545.         add     edi,4
  1546.         mov     cx,199
  1547.         rep     movsd
  1548.         ret
  1549. ClearPBuf ENDP
  1550.  
  1551. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1552. ;  Function to add one polygon buffer to another
  1553. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1554. ; IN: ESI -> Source polygon buffer (won't be changed)
  1555. ;     EDI -> Dest. polygon buffer (will be changed)
  1556.         EVEN
  1557. AddPBuf PROC
  1558.         mov     cx,200
  1559. APBML:  mov     ax,[esi]                 ; Left X coor
  1560.         cmp     ax,[edi]
  1561.         jg      APBL0
  1562.         mov     [edi],ax
  1563. APBL0:  mov     ax,[esi+2]
  1564.         cmp     ax,[edi+2]
  1565.         jl      APBL1
  1566.         mov     [edi+2],ax
  1567. APBL1:  add     esi,4
  1568.         add     edi,4
  1569.         dec     cx
  1570.         jnz     APBML
  1571.         ret
  1572. AddPBuf ENDP
  1573.  
  1574. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1575. ;  Function to dump a polygon buffer 
  1576. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1577. ; IN: ESI -> Polygon buffer
  1578. ;     AL :  Color
  1579. DPBClr  DB ?
  1580. DPBLeft DB 0Fh,0Eh,0Ch,08h
  1581. DPBRight DB 00h,01h,03,07h
  1582.  
  1583.         EVEN
  1584. DumpPBuf PROC
  1585.         mov     [DPBClr],al             ; Store color for latter use
  1586.         ; Init parameters for the 200 scans loop
  1587.         movzx   edi,[VGASeg]
  1588.         shl     edi,4
  1589.         sub     edi,_code32a
  1590.         mov     cx,200
  1591. DPBML:  push    cx
  1592.         push    edi
  1593.         push    esi
  1594.         mov     bx,[esi]
  1595.         cmp     bx,319
  1596.         jg      DPBL1                   ; Don't draw, completely out-right
  1597.         mov     cx,[esi+2]
  1598.         cmp     cx,0
  1599.         jl      DPBL1                   ; Don't draw, completely out-left
  1600.         cmp     bx,0
  1601.         jge     DPBL2
  1602.         xor     bx,bx
  1603.         mov     [esi],bx
  1604. DPBL2:  cmp     cx,319
  1605.         jle     DPBL3
  1606.         mov     cx,319
  1607.         mov     [esi+2],cx
  1608. DPBL3:  ; Choose: Only one | Left & Right | Left & Middle & Right
  1609.         shr     bx,2
  1610.         shr     cx,2
  1611.         sub     cx,bx
  1612.         jz      DPBL5                   ; Draw: both points in same 4pixel
  1613.         dec     cx
  1614.         jz      DPBL6                   ; Draw: points in adjacent 4pixels
  1615.  
  1616.         ; Draw three parts
  1617.         movzx   ebx,WORD PTR [esi]
  1618.         movzx   ecx,WORD PTR [esi+2]
  1619.  
  1620.         ; Now draw left part
  1621.         mov     ebp,ebx
  1622.         shr     ebp,2
  1623.         add     edi,ebp
  1624.         mov     ebp,ebx
  1625.         and     ebp,3
  1626.         mov     ah,DPBLeft[ebp]
  1627.         mov     al,2                    ; Map mask register
  1628.         mov     dx,3C4h
  1629.         out     dx,ax                   ; Set this reg
  1630.         mov     al,[DPBClr]
  1631.         stosb                           ; Draw and DI++
  1632.         
  1633.         ; Now draw middle part
  1634.         mov     ax,0F02h
  1635.         out     dx,ax                   ; Map mask reg: all planes
  1636.         mov     ebp,ecx
  1637.         and     bl,0FCh
  1638.         sub     ebp,ebx
  1639.         shr     ebp,2
  1640.         dec     ebp
  1641.         xchg    ecx,ebp
  1642.         mov     ebx,ecx
  1643.         shr     ecx,1
  1644.         mov     al,[DPBClr]
  1645.         or      ecx,ecx
  1646.         jz      DPBL7
  1647.         mov     ah,al
  1648.         rep     stosw                   ; Draw middle 2*(n%2) 4pixels
  1649. DPBL7:  and     bl,1
  1650.         jz      DPBL4
  1651.         stosb                           ; Draw last 4pixel if necessary
  1652. DPBL4:     
  1653.         ; Now draw right part
  1654.         and     ebp,3
  1655.         mov     ah,DPBRight[ebp]
  1656.         mov     al,2
  1657.         out     dx,ax
  1658.         mov     al,[DPBClr]
  1659.         stosb
  1660.         jmp     DPBL1
  1661.         
  1662. DPBL5:  ; Draw if both points are in the same 4pixel
  1663.         movzx   ebx,WORD PTR [esi]
  1664.         mov     ebp,ebx
  1665.         shr     ebp,2
  1666.         add     edi,ebp
  1667.         and     ebx,3
  1668.         mov     ah,DPBLeft[ebx]
  1669.         movzx   ebx,WORD PTR [esi+2]
  1670.         and     ebx,3
  1671.         and     ah,DPBRight[ebx]
  1672.         mov     al,2
  1673.         mov     dx,3C4h
  1674.         out     dx,ax
  1675.         mov     al,[DPBClr]
  1676.         stosb
  1677.         jmp     DPBL1
  1678.  
  1679. DPBL6:  ; Draw if both points are in adjacent 4pixels
  1680.         movzx   ebx,WORD PTR [esi]
  1681.         mov     ebp,ebx
  1682.         shr     ebp,2
  1683.         add     edi,ebp
  1684.         and     ebx,3
  1685.         mov     ah,DPBLeft[ebx]
  1686.         mov     al,2
  1687.         mov     dx,3C4h
  1688.         out     dx,ax
  1689.         mov     al,[DPBClr]
  1690.         stosb
  1691.         movzx   ebx,WORD PTR [esi+2]
  1692.         and     ebx,3
  1693.         mov     ah,DPBRight[ebx]
  1694.         mov     al,2
  1695.         out     dx,ax
  1696.         mov     al,[DPBClr]
  1697.         stosb
  1698.         ;jmp     DPBL1
  1699.         
  1700.  
  1701.         ; Keep on with the loop
  1702. DPBL1:  pop     esi
  1703.         pop     edi
  1704.         pop     cx
  1705.         add     edi,80d
  1706.         add     esi,4
  1707.         dec     cx
  1708.         jnz     DPBML
  1709.         ret
  1710. DumpPBuf ENDP
  1711.  
  1712. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1713. ;  Function to insert a line into a polygon buffer 
  1714. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1715. ; IN: EDI -> Polygon buffer
  1716. ;
  1717.         EVEN
  1718. ALPBX1  DW ?
  1719. ALPBY1  DW ?
  1720. ALPBX2  DW ?
  1721. ALPBY2  DW ?
  1722.  
  1723.                 DD ?
  1724. ALPBAdjFrac     DD 0
  1725.  
  1726.                 DD 1
  1727. ALPBAdjCoorX    DD 0
  1728.  
  1729.         EVEN
  1730. AddLineToPBuf PROC
  1731.         movzx   eax,WORD PTR [ALPBY2]
  1732.         movzx   ebx,WORD PTR [ALPBY1]
  1733.         cmp     eax,ebx
  1734.         je      _ret
  1735.         ja      ALPBL1                  ; Y2 > Y1 => don't swap
  1736.         mov     [ALPBY1],ax
  1737.         mov     [ALPBY2],bx
  1738.         xchg    eax,ebx
  1739.         movzx   ecx,WORD PTR [ALPBX1]
  1740.         movzx   edx,WORD PTR [ALPBX2]
  1741.         mov     [ALPBX1],dx
  1742.         mov     [ALPBX2],cx
  1743. ALPBL1: sub     eax,ebx
  1744.         mov     ebp,eax                 ; EBP = dY
  1745.         shl     ebx,2
  1746.         add     edi,ebx
  1747.         mov     ecx,eax
  1748.         inc     ecx                     ; ECX = dY + 1
  1749.         mov     ax,[ALPBX2]
  1750.         sub     ax,[ALPBX1]             ; AX = dX
  1751.         movsx   eax,ax
  1752.         jns     ALPBL4                  ; Going from left to right
  1753.         neg     eax                     ; Make dX >= 0
  1754.         mov     [ALPBAdjCoorX-4],-1     ; Coor adjusts negative
  1755. ALPBL4:
  1756.         cdq
  1757.         idiv    ebp                     ; EAX = dX / dY
  1758.         mov     esi,edx                 ; ESI = dX % dY
  1759.         mov     edx,eax                 ; EDX = dX / dY
  1760.         neg     ebp                     ; EBP = - dY
  1761.         mov     eax,ebp
  1762.         add     eax,eax                 ; EAX = - 2 * dY
  1763.         mov     [ALPBAdjFrac-4],eax
  1764.         movzx   eax,[ALPBX1]            ; EAX = X1
  1765.         add     esi,esi                 ; ESI = 2 * (dX % dY)
  1766.         cmp     DWORD PTR [ALPBAdjCoorX-4],1
  1767.         je      ALPBML
  1768.         neg     edx
  1769. ALPBML: cmp     ax,[edi]
  1770.         jg      ALPBL2                  ; Don't adjust left X
  1771.         mov     [edi],ax
  1772. ALPBL2: cmp     ax,[edi+2]
  1773.         jl      ALPBL3
  1774.         mov     [edi+2],ax
  1775. ALPBL3: add     edi,4
  1776.         add     eax,edx                 ; Increment X always
  1777.         add     ebp,esi                 ; Increment fractional part
  1778.         sbb     ebx,ebx
  1779.         shl     ebx,2
  1780.         add     eax,ALPBAdjCoorX[ebx]   ; Adjust Coor X (1 or 0)
  1781.         add     ebp,ALPBAdjFrac[ebx]    ; Adjust fractional part (0 or -2.dY)
  1782.         dec     ecx
  1783.         jnz     ALPBML
  1784.         mov     [ALPBAdjCoorX-4],1
  1785.         ret
  1786. AddLineToPBuf ENDP
  1787.  
  1788. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1789. ;  Main function
  1790. ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1791. I = 0
  1792. prueba label word
  1793. REPT 200
  1794.   DW 0, 0
  1795. ENDM
  1796.  
  1797. _main:
  1798.         sti
  1799. Main    PROC
  1800.         mov     v86r_ax,0013h
  1801.         mov     al,10h
  1802.         int     33h                     ; Standard 320x200x256 vmode
  1803.         mov     dx,3C4h
  1804.         mov     al,04
  1805.         out     dx,al
  1806.         inc     dx
  1807.         in      al,dx                   ; Read Sequencer memory mode
  1808.         and     al,NOT 8                ; register and unCHAIN4
  1809.         out     dx,al
  1810.  
  1811.         mov     dx,3C4h
  1812.         mov     ax,0F02h                ; Map Mask register = 1111b
  1813.         out     dx,ax
  1814.         mov     edi,0A0000h
  1815.         sub     edi,_code32a
  1816.         xor     eax,eax                 ; Fill with zeros
  1817.         mov     ecx,16384d              ; Dwords in each map
  1818.         rep     stosd
  1819.  
  1820.         mov     dx,3D4h
  1821.         mov     al,14h
  1822.         out     dx,al
  1823.         inc     dx
  1824.         in      al,dx
  1825.         and     al,NOT 64               ; Turn off DWORD mode
  1826.         out     dx,al
  1827.  
  1828.         mov     dx,3D4h
  1829.         mov     al,17h
  1830.         out     dx,al
  1831.         inc     dx
  1832.         in      al,dx
  1833.         or      al,64                   ; Turn on BYTE mode
  1834.         out     dx,al
  1835.  
  1836.         cmp     [Mode],WIREFRAME
  1837.         jnz     ML4
  1838.         mov     [LinesBufferPtr],OFFSET LinesBuffer1
  1839.         mov     [NumBufferedLinesPtr],OFFSET NumBufferedLines1
  1840.         mov     [NumBufferedLines1],0
  1841.         mov     [NumBufferedLines2],0
  1842.         jmp     ML5
  1843.    ML4: mov     [LinesBufferPtr],OFFSET LinesBuffer1
  1844.         mov     edi,OFFSET LinesBuffer1
  1845.         call    ClearPBuf
  1846.         mov     edi,OFFSET LinesBuffer2
  1847.         call    ClearPBuf
  1848.    ML5:
  1849.         mov     [QuitPrg],0
  1850.         mov     [ZN],128
  1851. MMainLoop:
  1852.         SetBorder 2
  1853.         call    DoSeq
  1854.         SetBorder 3
  1855.         call    CalcM
  1856.         SetBorder 4
  1857.         call    CalcDist
  1858.         SetBorder 5
  1859.         call    WToCam
  1860.         SetBorder 6
  1861.         call    BuildClip
  1862.         SetBorder 7
  1863.         call    SortByDist
  1864.         SetBorder 8
  1865.         cmp     [Mode],WIREFRAME
  1866.         jnz     ML0
  1867.         call    DrawWire
  1868.         jmp     ML1
  1869.    ML0: call    DrawSolid
  1870.    ML1:
  1871.         SetBorder 0
  1872.  
  1873.         mov     dx,3DAh
  1874. MWaitA: in      al,dx
  1875.         test    al,8
  1876.         jnz     MWaitA
  1877.  
  1878.         mov     ax,[VGASeg]             ; Show just-drawn page
  1879.         mov     cl,4
  1880.         shl     ax,cl
  1881.         mov     al,0Ch                  ; Start Address Hi register
  1882.         mov     dx,3D4h
  1883.         out     dx,ax
  1884.  
  1885.         mov     dx,3DAh
  1886. MWait0: in      al,dx
  1887.         test    al,8
  1888.         jz      MWait0
  1889.  
  1890.         mov     dx,3DAh
  1891. MWait1: in      al,dx
  1892.         test    al,8
  1893.         jnz     MWait1
  1894.  
  1895.         SetBorder 1
  1896.  
  1897.         mov     eax,[LinesBufferPtr]
  1898.         xor     eax,OFFSET LinesBuffer1
  1899.         xor     eax,OFFSET LinesBuffer2
  1900.         mov     [LinesBufferPtr],eax
  1901.         mov     eax,[NumBufferedLinesPtr]
  1902.         xor     eax,OFFSET NumBufferedLines1
  1903.         xor     eax,OFFSET NumBufferedLines2
  1904.         mov     [NumBufferedLinesPtr],eax
  1905.         xor     [VGASeg],400h
  1906.         cmp     [Mode],WIREFRAME
  1907.         jnz     ML2
  1908.         call    EraseBufferedLines
  1909.         jmp     ML3
  1910.    ML2: call    EraseBufferedPolys
  1911.    ML3:
  1912.  
  1913.         mov     ax,[QuitPrg]
  1914.         or      ax,ax
  1915.         jnz     MExit
  1916.         jmp     MMainLoop
  1917.  
  1918. MExit:  mov     v86r_ax,0003
  1919.         mov     al,10h
  1920.         int     33h
  1921.         mov     edx,OFFSET ByeMsg
  1922.         add     edx,_code32a
  1923.         mov     ebx,edx
  1924.         and     dx,0Fh
  1925.         mov     v86r_dx,dx
  1926.         shr     ebx,4
  1927.         mov     v86r_ds,bx
  1928.         mov     v86r_ah,9
  1929.         mov     al,21h
  1930.         int     33h
  1931.         jmp     _exit
  1932. Main    ENDP
  1933.  
  1934. code32  ends
  1935.  
  1936.         END
  1937.